#include "include/common/monitoring/metrics.h"
#include <sstream>
#include <iomanip>
#include <algorithm>
#include <cmath>  // 添加cmath头文件，提供isinf函数

// Metric基类实现
Metric::Metric(const std::string& name, const std::string& help,
               const std::unordered_map<std::string, std::string>& labels)
    : name_(name), help_(help), labels_(labels) {}

const std::string& Metric::getName() const {
    return name_;
}

const std::string& Metric::getHelp() const {
    return help_;
}

const std::unordered_map<std::string, std::string>& Metric::getLabels() const {
    return labels_;
}

// Counter实现
Counter::Counter(const std::string& name, const std::string& help,
                 const std::unordered_map<std::string, std::string>& labels)
    : Metric(name, help, labels), value_(0) {}

void Counter::inc(double value) {
    if (value < 0) {
        return; // 计数器不允许减少
    }
    // 修复std::atomic<double>的+=操作
    double current = value_.load();
    double desired = current + value;
    while (!value_.compare_exchange_weak(current, desired)) {
        desired = current + value;
    }
}

double Counter::getValue() const {
    return value_;
}

MetricType Counter::getType() const {
    return MetricType::COUNTER;
}

std::string Counter::exportMetric() const {
    std::ostringstream ss;
    ss << "# HELP " << name_ << " " << help_ << "\n";
    ss << "# TYPE " << name_ << " counter\n";
    
    ss << name_;
    
    // 添加标签
    if (!labels_.empty()) {
        ss << "{";
        bool first = true;
        for (const auto& label : labels_) {
            if (!first) {
                ss << ",";
            }
            ss << label.first << "=\"" << label.second << "\"";
            first = false;
        }
        ss << "}";
    }
    
    ss << " " << std::fixed << std::setprecision(6) << getValue() << "\n";
    return ss.str();
}

// Gauge实现
Gauge::Gauge(const std::string& name, const std::string& help,
             const std::unordered_map<std::string, std::string>& labels)
    : Metric(name, help, labels), value_(0) {}

void Gauge::set(double value) {
    value_ = value;
}

void Gauge::inc(double value) {
    // 修复std::atomic<double>的+=操作
    double current = value_.load();
    double desired = current + value;
    while (!value_.compare_exchange_weak(current, desired)) {
        desired = current + value;
    }
}

void Gauge::dec(double value) {
    // 修复std::atomic<double>的-=操作
    double current = value_.load();
    double desired = current - value;
    while (!value_.compare_exchange_weak(current, desired)) {
        desired = current - value;
    }
}

double Gauge::getValue() const {
    return value_;
}

MetricType Gauge::getType() const {
    return MetricType::GAUGE;
}

std::string Gauge::exportMetric() const {
    std::ostringstream ss;
    ss << "# HELP " << name_ << " " << help_ << "\n";
    ss << "# TYPE " << name_ << " gauge\n";
    
    ss << name_;
    
    // 添加标签
    if (!labels_.empty()) {
        ss << "{";
        bool first = true;
        for (const auto& label : labels_) {
            if (!first) {
                ss << ",";
            }
            ss << label.first << "=\"" << label.second << "\"";
            first = false;
        }
        ss << "}";
    }
    
    ss << " " << std::fixed << std::setprecision(6) << getValue() << "\n";
    return ss.str();
}

// Histogram实现
Histogram::Histogram(const std::string& name, const std::string& help,
                     const std::vector<double>& buckets,
                     const std::unordered_map<std::string, std::string>& labels)
    : Metric(name, help, labels), sum_(0), count_(0) {
    
    // 确保桶的上界是有序的
    std::vector<double> sortedBuckets = buckets;
    std::sort(sortedBuckets.begin(), sortedBuckets.end());
    
    // 创建所有的桶
    for (double bound : sortedBuckets) {
        buckets_.push_back(HistogramBucket(bound));
    }
    
    // 添加一个 +Inf 桶
    buckets_.push_back(HistogramBucket(std::numeric_limits<double>::infinity()));
}

void Histogram::observe(double value) {
    // 更新所有大于等于value的桶
    for (auto& bucket : buckets_) {
        if (value <= bucket.upperBound) {
            bucket.count++;
        }
    }
    
    // 更新总和和计数
    // 修复std::atomic<double>的+=操作
    double current = sum_.load();
    double desired = current + value;
    while (!sum_.compare_exchange_weak(current, desired)) {
        desired = current + value;
    }
    count_++;
}

MetricType Histogram::getType() const {
    return MetricType::HISTOGRAM;
}

std::string Histogram::exportMetric() const {
    std::ostringstream ss;
    ss << "# HELP " << name_ << " " << help_ << "\n";
    ss << "# TYPE " << name_ << " histogram\n";
    
    // 导出桶
    for (const auto& bucket : buckets_) {
        ss << name_ << "_bucket";
        
        // 添加标签
        ss << "{";
        bool first = true;
        
        // 先添加自定义标签
        for (const auto& label : labels_) {
            if (!first) {
                ss << ",";
            }
            ss << label.first << "=\"" << label.second << "\"";
            first = false;
        }
        
        // 添加le标签
        if (!first) {
            ss << ",";
        }
        
        if (std::isinf(bucket.upperBound)) {
            ss << "le=\"+Inf\"";
        } else {
            ss << "le=\"" << std::fixed << std::setprecision(6) << bucket.upperBound << "\"";
        }
        
        ss << "} " << bucket.count << "\n";
    }
    
    // 导出总和
    ss << name_ << "_sum";
    if (!labels_.empty()) {
        ss << "{";
        bool first = true;
        for (const auto& label : labels_) {
            if (!first) {
                ss << ",";
            }
            ss << label.first << "=\"" << label.second << "\"";
            first = false;
        }
        ss << "}";
    }
    ss << " " << std::fixed << std::setprecision(6) << sum_ << "\n";
    
    // 导出计数
    ss << name_ << "_count";
    if (!labels_.empty()) {
        ss << "{";
        bool first = true;
        for (const auto& label : labels_) {
            if (!first) {
                ss << ",";
            }
            ss << label.first << "=\"" << label.second << "\"";
            first = false;
        }
        ss << "}";
    }
    ss << " " << count_ << "\n";
    
    return ss.str();
}

// Timer实现
Timer::Timer(const std::string& name, const std::string& help,
             const std::unordered_map<std::string, std::string>& labels)
    : Histogram(name, help, {0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10}, labels) {}

void Timer::start() {
    std::lock_guard<std::mutex> lock(mutex_);
    startTime_ = std::chrono::high_resolution_clock::now();
}

void Timer::stop() {
    std::lock_guard<std::mutex> lock(mutex_);
    auto endTime = std::chrono::high_resolution_clock::now();
    auto duration = std::chrono::duration<double>(endTime - startTime_).count();
    observe(duration);
}

Timer::TimeGuard Timer::time() {
    return TimeGuard(*this);
}

MetricType Timer::getType() const {
    return MetricType::TIMER;
}

// TimeGuard实现
Timer::TimeGuard::TimeGuard(Timer& timer)
    : timer_(timer) {
    startTime_ = std::chrono::high_resolution_clock::now();
}

Timer::TimeGuard::~TimeGuard() {
    auto endTime = std::chrono::high_resolution_clock::now();
    auto duration = std::chrono::duration<double>(endTime - startTime_).count();
    timer_.observe(duration);
}

// MetricRegistry实现
MetricRegistry& MetricRegistry::instance() {
    static MetricRegistry instance;
    return instance;
}

void MetricRegistry::registerMetric(std::shared_ptr<Metric> metric) {
    std::lock_guard<std::mutex> lock(mutex_);
    metrics_.push_back(metric);
}

std::vector<std::shared_ptr<Metric>> MetricRegistry::getMetrics() const {
    std::lock_guard<std::mutex> lock(mutex_);
    return metrics_;
}

void MetricRegistry::clear() {
    std::lock_guard<std::mutex> lock(mutex_);
    metrics_.clear();
}

std::string MetricRegistry::exportAllMetrics() const {
    std::lock_guard<std::mutex> lock(mutex_);
    std::ostringstream ss;
    
    for (const auto& metric : metrics_) {
        ss << metric->exportMetric();
    }
    
    return ss.str();
}

// 便捷方法实现
std::shared_ptr<Counter> createCounter(const std::string& name, const std::string& help,
                                     const std::unordered_map<std::string, std::string>& labels) {
    auto counter = std::make_shared<Counter>(name, help, labels);
    MetricRegistry::instance().registerMetric(counter);
    return counter;
}

std::shared_ptr<Gauge> createGauge(const std::string& name, const std::string& help,
                                 const std::unordered_map<std::string, std::string>& labels) {
    auto gauge = std::make_shared<Gauge>(name, help, labels);
    MetricRegistry::instance().registerMetric(gauge);
    return gauge;
}

std::shared_ptr<Histogram> createHistogram(const std::string& name, const std::string& help,
                                         const std::vector<double>& buckets,
                                         const std::unordered_map<std::string, std::string>& labels) {
    auto histogram = std::make_shared<Histogram>(name, help, buckets, labels);
    MetricRegistry::instance().registerMetric(histogram);
    return histogram;
}

std::shared_ptr<Timer> createTimer(const std::string& name, const std::string& help,
                                 const std::unordered_map<std::string, std::string>& labels) {
    auto timer = std::make_shared<Timer>(name, help, labels);
    MetricRegistry::instance().registerMetric(timer);
    return timer;
} 